home *** CD-ROM | disk | FTP | other *** search
- /*
- File: EnablerSmpl.c
-
- Contains: This is a sample enabler for an ethernet PC Card, which demonstrates how to
- create a port module
- registration item and set a custom module name that will be used to
- identify the device driver.
-
- Written by: Carl Fallis - writer of the original sample on which this sample is based
- Hiroko Nishimura - modified the sample to support the Ratoc REX-5589 Ethernet
- PC Card.
- Rich Kubota - modified to demonstrate handling of custom port registration
-
- Copyright: Copyright © 1996-1999 by Apple Computer, Inc., All Rights Reserved.
-
- You may incorporate this Apple sample source code into your program(s) without
- restriction. This Apple sample source code has been provided "AS IS" and the
- responsibility for its operation is yours. You are not permitted to redistribute
- this Apple sample source code as "Apple sample source code" after having made
- changes. If you're going to re-distribute the source, we require that you make
- it clear in the source that the code was descended from Apple sample source
- code, but that you've made changes.
-
- Change History (most recent first):
- 8/16/1999 Karl Groethe Updated for Metrowerks Codewarror Pro 2.1
-
-
- */
-
- #include <Types.h>
- #include <Errors.h>
- #include <Devices.h>
- #include <Gestalt.h>
- #include <CodeFragments.h>
- //#include <DriverServices.h>
- #include <PCCardEnablerPlugin.h>
- #include <PCCardTuples.h>
- #include <OpenTptModule.h>
- #include <OpenTptPCISupport.h>
- #include <OpenTptDevLinks.h>
- #include "EnablerSample.h"
- #include "MyPortCalls.h"
-
- // use the TupleDumper PPC utility which comes with the PC Card DDK to display the data
- // associated with the following Tuples. The following are used with the _IdentifyCard call
- // to verify that the proper card is being supported.
-
- const unsigned char kCISTPL_VERS_1_Data[] = "\4\1PCMCIA LAN MBH10304 ES\0 01\0\xff";
-
- const unsigned char kCISTPL_CONFIG_Data[] = {0x05,0x20,0xF0,0x03,0x03,0x00,0xFF};
-
- const unsigned char kCISTPL_CFTABLE_ENTRY_Data[] = {0xE0,0xC1,0x99,0x5F,0x55,0xC5,0x4B,0xD5,
- 0x19,0x86,0x10,0x26,0x45,0x65,0x30,0xFF,
- 0xFF,0x20,0xFF};
-
- //----------------------------------------------------------------------
- // Local Prototypes
-
- typedef PCCardTupleIterator PCCardTupleIteratorPtr;
-
- OSStatus MyValidateHardware(const RegEntryID * lpCardEntry);
- OSStatus MyHandleCardEvent(const RegEntryID *cardRef, PCCardEvent theEvent);
- OSStatus MyGetFirstTuple(UInt32 socket, UInt32 device, PCCardTupleIteratorPtr lpTupleIterator,
- Byte desiredTuple, void *lptupleData, UInt32 *lpTupleBufferSize, Byte *lpFoundTuple);
- OSStatus MyGetNextTuple(PCCardTupleIteratorPtr tupleIterator, Byte desiredTuple, void *tupleData, ByteCount *tupleBufferSize, Byte *foundTuple);
-
-
- OSStatus _IdentifyCard(const RegEntryID * lpCardEntry);
- Boolean CheckVers1Tuple(unsigned char * data, char * manufacturerName, char * cardName);
- OSStatus CreatePortProperties(const RegEntryID *cardRef);
- OSStatus MyAddDeviceProperties(const RegEntryID *cardRef, UInt32 device);
- OSStatus MyFinalizeDevice(UInt32 socket, UInt32 device, const RegEntryID *deviceRef);
- void CallPortScanner(void);
- void EnablerOfflinePort(const RegEntryID *cardRef);
- //----------------------------------------------------------------------
- // Globals
-
-
- #pragma export on
-
- // --------------------
- // Here's the exported Driver Descriptor
- DriverDescription TheDriverDescription = {
- /*
- * Signature info
- */
- kTheDescriptionSignature, /* OSType driverDescSignature */
- kInitialDriverDescriptor, /* DriverDescVersion driverDescVersion */
- /*
- * DriverType driverType - these are defined in
- */
- kPluginNamePString, /* Name of hardware */
- kVersionMajor, kVersionMinor, /* NumVersion version */
- kVersionStage, kVersionNonRel,
-
- /*
- * DriverOSRuntime driverOSRuntimeInfo
- */
- kDriverIsLoadedUponDiscovery | /* Loader runtime options */
- kDriverIsUnderExpertControl, /* I/O expert handles loads/opens */
- kPluginNamePString, /* Str31 driverName (OpenDriver param) */
- 0, 0, 0, 0, 0, 0, 0, 0, /* UInt32 driverDescReserved[8] */
-
- /*
- * DriverOSService Information. This section contains a vector count followed by
- * a vector of structures, each defining a driver service.
- */
- 1, /* ServiceCount nServices */
-
- /*
- * DriverServiceInfo service[0]
- */
- kServiceCategoryPCCard, /* OSType serviceCategory */
- kServiceTypePCCardEnabler, /* OSType serviceType */
-
- 1, 0,developStage, 1
- };
-
-
-
- // --------------------
- // Here's the exported Plugin Function Table…
- PCCardEnablerPluginDispatchTable ThePluginDispatchTable =
- {
- /* PCCardEnablerPluginHeader */
- { kPCCardEnablerPluginCurrentVersion, 0, 0, 0 },
-
- /* CEValidateHardwareProc */ MyValidateHardware,
- /* CEInitializeProc */ CEInitializeCard,
- /* CECleanupProc */ CEFinalizeCard,
- /* CEPowerManagementProc */ CEPowerManagement,
-
- /* CEHandleEventProc */ CEHandleCardEvent,
- /* CEGetCardInfoProc */ CEGetCardInfo,
- /* CEAddCardPropertiesProc */ CEAddCardProperties,
- /* CEGetDeviceCountProc */ CEGetDeviceCount,
-
- /* CEGetDeviceNameProc */ CEGetDeviceName,
- /* CEGetDeviceCompatibleNameProc */ CEGetDeviceCompatibleNames,
- /* CEGetDeviceTypeProc */ CEGetDeviceType,
- /* CEGetDeviceTypeNameProc */ CEGetDeviceTypeName,
- /* CEAddDevicePropertiesProc */ MyAddDeviceProperties,
- /* CEConfigureDeviceProc */ CEConfigureDevice,
- /* CEFinalizeDeviceProc */ MyFinalizeDevice,
-
- /* CEValidateCISProc */ CEValidateCIS,
- /* CEGetFirstTupleProc */ MyGetFirstTuple,
- /* CEGetNextTupleProc */ MyGetNextTuple,
-
- /* InterruptHandler */ CEDefaultInterruptHandler,
- /* InterruptEnabler */ NULL,
- /* InterruptDisabler */ NULL
- };
-
-
- //----------------------------------------------------------------------
- // Determine whether the plugin can support this card.
- // Returning noErr means that the card is supported
- OSStatus MyValidateHardware(const RegEntryID *lpCardEntry)
- {
- OSStatus err;
-
- #if DEBUG
- DebugStr("\pCustomCardEnabler: MyValidateHardware");
- #endif
- if (!(lpCardEntry)) return(paramErr);
-
- // see if we are supposed to handle this card, set global card id
- err = _IdentifyCard(lpCardEntry);
-
- #if DEBUG1
- if (err == noErr) DebugStr("\p Enabler will handle this card!;g");
- #endif
- return(err);
- }
-
-
- //----------------------------------------------------------------------
- // Look to see if this is a card we are supposed to handle
- // If it is return noErr, other wise return kUnsupportedCardErr
- //
- // Identification of the IBM OEM Ethernet card
- // 1) check the manufacturer's ID
- // 2) check the vers 1 for IBM Corp Ethernet
- // 3) check for the config table entry for the bad entry so that we are sure that
- // this is the correct card we say it is our card
- OSStatus _IdentifyCard(const RegEntryID *lpCardEntry)
- {
- PCCardTupleIteratorPtr iter;
- OSStatus err = noErr;
- UInt32 size=MAX_TUPLE_SIZE, socket, device;
- Boolean match = false;
- int i=0;
-
-
- #if DEBUG
- DebugStr("\pCustomCardEnabler: _IdentifyCard");
- #endif
-
- if(!(lpCardEntry) ) return(paramErr);
-
- err = CEGetSocketAndDeviceFromRegEntry(lpCardEntry, &socket, &device);
- if (err != noErr)
- return(err);
-
- iter = PCCardNewTupleIterator();
- if (iter == NULL)
- return memFullErr;
-
- err = CECompareCISTPL_MANFID(lpCardEntry,
- kManifID,
- kManifInfo,
- &match);
-
- if ((err == noErr) && (match == true))
- {
- // do other checking if required like calling CSGetFirstTuple
- // to get more tuple info to compare against
- }
- else
- err = kUnsupportedCardErr;
-
- // dispose of the tuple iterator
- PCCardDisposeTupleIterator(iter);
-
- return(err);
- }
-
- //----------------------------------------------------------------------
- // Look for the kPCCardInsertionMessage as the event
- OSStatus MyHandleCardEvent(const RegEntryID *cardRef, PCCardEvent theEvent)
- {
- OSStatus err = noErr;
-
- #if DEBUG
-
- DebugStr("\pMyHandleCardEvent called");
- #endif
-
- switch (theEvent)
- {
- case kPCCardInsertionMessage:
- #if DEBUG1
- DebugStr("\pkPCCardInsertionMessage event passed to MyHandleCardEvent;g");
- #endif
- break;
-
- case kPCCardEjectionRequestMessage:
- case kPCCardRemovalMessage:
- #if DEBUG
- DebugStr("\p kPCCardRemovalMessage called");
- #endif
- // EnablerOfflinePort(cardRef);
- break;
- }
-
- if (err == noErr)
- // call the default HandleEventProc to complete processing of the event.
- err = CEHandleCardEvent(cardRef, theEvent);
-
- return err;
- }
-
-
- //----------------------------------------------------------------------
- OSStatus MyGetFirstTuple(UInt32 socket, UInt32 device,
- PCCardTupleIteratorPtr lpTupleIterator,
- Byte desiredTuple,
- void *lpTupleData,
- UInt32 *lpTupleBufferSize,
- Byte *lpFoundTuple)
- {
- OSStatus err = noErr;
- unsigned char *dataPtr = (unsigned char *)lpTupleData;
- UInt32 i=0;
-
-
- #if DEBUG
- // DebugStr("\pCustomCardEnabler: MyGetFirstTuple");
- #endif
- if(!(lpTupleIterator && lpFoundTuple && lpTupleData && *lpTupleBufferSize))
- return(paramErr);
-
-
-
- err = CSGetFirstTuple(socket, device,lpTupleIterator,desiredTuple,
- lpTupleData,lpTupleBufferSize,lpFoundTuple);
- if (err != noErr)
- return(err);
-
- if (*lpTupleBufferSize == 0)
- return(err);
-
- if (*lpFoundTuple == CISTPL_VERS_1)
- {
- #if DEBUG1
- // DebugStr("\pCISTPL_VERS_1");
- #endif
- for( i = 0; i < sizeof(kCISTPL_VERS_1_Data); i++)
- dataPtr[i] = kCISTPL_VERS_1_Data[i];
-
- *lpTupleBufferSize = sizeof(kCISTPL_VERS_1_Data);
-
- }
-
- if (*lpFoundTuple == CISTPL_CONFIG)
- {
- #if DEBUG1
- DebugStr("\pCISTPL_CONFIG");
- #endif
- for( i = 0; i < sizeof(kCISTPL_CONFIG_Data); i++)
- dataPtr[i] = kCISTPL_CONFIG_Data[i];
- *lpTupleBufferSize = sizeof(kCISTPL_CONFIG_Data);
- }
- if (*lpFoundTuple == CISTPL_CFTABLE_ENTRY)
- {
- #if DEBUG1
- DebugStr("\pCISTPL_CFTABLE_ENTRY");
- #endif
- for( i = 0; i < sizeof(kCISTPL_CFTABLE_ENTRY_Data); i++)
- dataPtr[i] = kCISTPL_CFTABLE_ENTRY_Data[i];
- *lpTupleBufferSize = sizeof(kCISTPL_CFTABLE_ENTRY_Data);
- }
-
- return(err);
- }
-
- //
- // MyGetNextTuple
- //
- OSStatus MyGetNextTuple(PCCardTupleIteratorPtr lpTupleIterator,
- Byte desiredTuple,
- void *lpTupleData,
- ByteCount *lpTupleBufferSize,
- Byte *lpFoundTuple)
- {
- OSStatus err = noErr;
- unsigned char *dataPtr = (unsigned char *)lpTupleData;
- UInt32 i=0;
-
-
- #if DEBUG
- // DebugStr("\pCustomCardEnabler: MyGetNextTuple");
- #endif
- if(!(lpTupleIterator && lpFoundTuple && lpTupleData && *lpTupleBufferSize))
- return(paramErr);
-
-
-
- err = CSGetNextTuple(lpTupleIterator, desiredTuple,lpTupleData,lpTupleBufferSize,
- lpFoundTuple);
- if (err != noErr)
- return(err);
-
-
- if (*lpTupleBufferSize == 0)
- return(err);
-
- if (*lpFoundTuple == CISTPL_VERS_1)
- {
- #if DEBUG1
- // DebugStr("\pCISTPL_VERS_1");
- #endif
- for( i = 0; i < sizeof(kCISTPL_VERS_1_Data); i++)
- dataPtr[i] = kCISTPL_VERS_1_Data[i];
- *lpTupleBufferSize = sizeof(kCISTPL_VERS_1_Data);
- }
- if (*lpFoundTuple == CISTPL_CONFIG)
- {
- #if DEBUG1
- DebugStr("\pCISTPL_CONFIG");
- #endif
- for( i = 0; i < sizeof(kCISTPL_CONFIG_Data); i++)
- dataPtr[i] = kCISTPL_CONFIG_Data[i];
- *lpTupleBufferSize = sizeof(kCISTPL_CONFIG_Data);
- }
-
- if (*lpFoundTuple == CISTPL_CFTABLE_ENTRY)
- {
- #if DEBUG1
- DebugStr("\pCISTPL_CFTABLE_ENTRY");
- #endif
- for( i = 0; i < sizeof(kCISTPL_CFTABLE_ENTRY_Data); i++)
- dataPtr[i] = kCISTPL_CFTABLE_ENTRY_Data[i];
- *lpTupleBufferSize = sizeof(kCISTPL_CFTABLE_ENTRY_Data);
- }
-
- return(err);
- }
-
-
- //----------------------------------------------------------------------
- // Pass in a VERS1 tuple and check that the manufacturer name and card name are
- // the the same as the ones passed in
- Boolean CheckVers1Tuple(unsigned char * data, char * manufacturerName, char * cardName)
- {
- unsigned char *ptr;
-
-
- #if DEBUG
- // DebugStr("\pCustomCardEnabler: CheckVers1Tuple");
- #endif
- // the manufacturer name is a null terminated string starting in byte three
- ptr = &(data[2]);
- if(CStrCmp((const char *) ptr, manufacturerName) == 0)
- {
- // the card name is a null terminated string that starts after the manufacturer name
- while(*ptr++)
- ;
- if(CStrCmp((const char *) ptr, cardName) != 0)
- return(false);
- }
- else
- return(false);
-
- // if we make it to here, both names match
- return(true);
- }
-
-
- OSStatus MyFinalizeDevice(UInt32 socket, UInt32 device, const RegEntryID *deviceRef)
- {
- OSStatus err;
- #if DEBUG
- DebugStr("\p MyFinalizeDevice called");
- #endif
- EnablerOfflinePort(deviceRef);
- err = CEFinalizeDevice(socket, device, deviceRef);
- return err;
- }
-
- OSStatus MyAddDeviceProperties(const RegEntryID *cardRef, UInt32 device)
- {
- #pragma unused ( device )
- OSStatus err;
-
- #if DEBUG
- DebugStr("\pCustomCardEnabler: MyAddDeviceProperties");
- #endif
-
- // This would be a great place to register a port, however, this creates a problem for
- // the shared library since this code could be called at start up time prior to
- // the availability of Open Transport. While I could weak link with OT, if the library
- // is not present, then even when the library becomes available, CFM will not relink
- // with the OT libraries. To handle this case, we implement a port scanner.
-
- err = CreatePortProperties(cardRef);
- CallPortScanner();
-
- return err;
- }
-
-
-
-
-